package com.gandong8.trace.tool.core;


import com.gandong8.trace.tool.util.TraceUtil;
import com.gandong8.trace.tool.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

/**
 * resources/META-INF/dubbo
 * com.alibaba.dubbo.rpc.Filter
 * dubboFilter=com.gandong8.trace.web.core.DubboRollbackTaskFilter
 *  <dubbo:provider filter="dubboFilter" />
 *  <dubbo:consumer filter="dubboFilter" />
 */
@Activate(group = {CommonConstants.CONSUMER, CommonConstants.PROVIDER}, order = -30000)
@Slf4j
public class DubboFilter implements Filter {

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation){
        long cnt = SystemClock.now();
        try {
            if (RpcContext.getContext().isConsumerSide()) {
                RpcContext.getContext().setAttachment(TraceUtil.TRACE_TAG, TraceUtil.getTraceId());
            } else {
                String traceId = RpcContext.getContext().getAttachment(TraceUtil.TRACE_TAG);
                if(traceId == null) {
                    traceId = TraceUtil.getTraceId();
                }
                TraceUtil.setLogTrace(traceId);
            }
        } catch (Exception e) {
            log.error("dubboFilterException", e);
        }
        try {
            return invoker.invoke(invocation);
        } finally {
            try {
                String method = invocation.getMethodName();
                String name = invoker.getInterface().getName();
                Object[] args = invocation.getArguments();
                String argsStr = JsonUtil.toStr(args);
                log.warn("Cost={};className={};method={};args={}", SystemClock.now() - cnt, name, method, argsStr);
            } catch (Exception e) {
                log.error("dubboInvokeException-aa", e);
            }
        }
    }
}
